]> dgit.raspbian.org Git - libde265.git/commitdiff
CVE-2024-38949 (Heap Buffer Overflow) and CVE-2024-38950 (crash)
authorTobias Frost <tobi@debian.org>
Sun, 20 Sep 2026 11:47:08 +0000 (13:47 +0200)
committerTobias Frost <tobi@debian.org>
Sun, 20 Sep 2026 11:47:08 +0000 (13:47 +0200)
Origin: https://github.com/strukturag/libde265/commit/4089de0845e0009e019be4ca5cbebaf2aee0a8ce
Bug: https://github.com/strukturag/libde265/issues/460
Bug-Debian: https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=1074416

as the version in bookworm is still using SDL1.2, the resize() function has
been backported for SDL1.2.
The display444as420() does not need backporting, as with SDL1.2 the faulty
pointer arimethic is not needed, SDL has separate buffers.
From 4089de0845e0009e019be4ca5cbebaf2aee0a8ce Mon Sep 17 00:00:00 2001
From: Dirk Farin <dirk.farin@gmail.com>
Date: Sun, 10 May 2026 22:37:53 +0200
Subject: [PATCH] dec265: fix SDL OOB on 4:4:4 streams and mid-stream
 resolution change (closes #460)

Gbp-Pq: Name CVE-2024-38949+CVE-2024-38950.patch

dec265/dec265.cc
dec265/sdl.cc
dec265/sdl.hh

index 8ddecfc2c9491441889f021fbc39eca8100e5fc2..f8b044b66acbd6e8ff816808a6f8f42048720608 100644 (file)
@@ -261,17 +261,20 @@ bool display_sdl(const struct de265_image* img)
 
   de265_chroma chroma = de265_get_chroma_format(img);
 
+  enum SDL_YUV_Display::SDL_Chroma sdlChroma;
+  switch (chroma) {
+  case de265_chroma_420:  sdlChroma = SDL_YUV_Display::SDL_CHROMA_420;  break;
+  case de265_chroma_422:  sdlChroma = SDL_YUV_Display::SDL_CHROMA_422;  break;
+  case de265_chroma_444:  sdlChroma = SDL_YUV_Display::SDL_CHROMA_444;  break;
+  case de265_chroma_mono: sdlChroma = SDL_YUV_Display::SDL_CHROMA_MONO; break;
+    default: sdlChroma = SDL_YUV_Display::SDL_CHROMA_MONO;
+  }
+
   if (!sdl_active) {
     sdl_active=true;
-    enum SDL_YUV_Display::SDL_Chroma sdlChroma;
-    switch (chroma) {
-    case de265_chroma_420:  sdlChroma = SDL_YUV_Display::SDL_CHROMA_420;  break;
-    case de265_chroma_422:  sdlChroma = SDL_YUV_Display::SDL_CHROMA_422;  break;
-    case de265_chroma_444:  sdlChroma = SDL_YUV_Display::SDL_CHROMA_444;  break;
-    case de265_chroma_mono: sdlChroma = SDL_YUV_Display::SDL_CHROMA_MONO; break;
-    }
-
-    sdlWin.init(width,height, sdlChroma);
+    if (!sdlWin.init(width,height, sdlChroma)) return true;
+  } else {
+    if (!sdlWin.resize(width,height, sdlChroma)) return true;
   }
 
   int stride,chroma_stride;
index a7afa1ce76fd72438e6ceeedb86c8dce551e1144..7b5603c0ab02baf3e87d9463343f8d6948757ea5 100644 (file)
@@ -96,6 +96,80 @@ bool SDL_YUV_Display::init(int frame_width, int frame_height, enum SDL_Chroma ch
   return true;
 }
 
+
+
+bool SDL_YUV_Display::resize(int frame_width, int frame_height, enum SDL_Chroma chroma)
+{
+  if (!mWindowOpen) {
+    return init(frame_width, frame_height, chroma);
+  }
+
+  // reduce image size to a multiple of 8, same rounding as init()
+  frame_width  &= ~7;
+  frame_height &= ~7;
+
+  if (frame_width == rect.w && frame_height == rect.h && mChroma == chroma) {
+    return true;
+  }
+
+  mChroma = chroma;
+
+  // The overlay is tied to the old dimensions/pixel format; it has to be
+  // freed and recreated at the new size (SDL 1.2 has no in-place resize).
+  if (mYUVOverlay) {
+    SDL_FreeYUVOverlay(mYUVOverlay);
+    mYUVOverlay = NULL;
+  }
+
+  const SDL_VideoInfo* info = SDL_GetVideoInfo();
+  if (!info) {
+    printf("SDL_GetVideoInfo() failed: %s\n", SDL_GetError());
+    mWindowOpen = false;
+    return false;
+  }
+
+  Uint8 bpp = info->vfmt->BitsPerPixel;
+
+  Uint32 vflags;
+  if (info->hw_available)
+    vflags = SDL_HWSURFACE;
+  else
+    vflags = SDL_SWSURFACE;
+
+  mScreen = SDL_SetVideoMode(frame_width, frame_height, bpp, vflags);
+  if (mScreen == NULL) {
+    printf("SDL: Couldn't set video mode to %dx%d,%d bpp: %s",
+           frame_width, frame_height, bpp, SDL_GetError());
+    mWindowOpen = false;
+    return false;
+  }
+
+  uint32_t pixelFormat;
+  switch (mChroma) {
+  case SDL_CHROMA_MONO: pixelFormat = SDL_YV12_OVERLAY; break;
+  case SDL_CHROMA_420:  pixelFormat = SDL_YV12_OVERLAY; break;
+  case SDL_CHROMA_422:  pixelFormat = SDL_YUY2_OVERLAY; break;
+  case SDL_CHROMA_444:  pixelFormat = SDL_YV12_OVERLAY; break;
+  default:              pixelFormat = SDL_YV12_OVERLAY; break;
+  }
+
+  mYUVOverlay = SDL_CreateYUVOverlay(frame_width, frame_height, pixelFormat, mScreen);
+  if (mYUVOverlay == NULL) {
+    printf("SDL: Couldn't recreate SDL YUV overlay: %s", SDL_GetError());
+    mWindowOpen = false;
+    return false;
+  }
+
+  rect.x = 0;
+  rect.y = 0;
+  rect.w = frame_width;
+  rect.h = frame_height;
+
+  return true;
+}
+
+
+
 void SDL_YUV_Display::display(const unsigned char *Y,
                               const unsigned char *U,
                               const unsigned char *V,
index 08f9578cd68296dac6661ab649164af8fd3c4e17..0ebc6745b7cfd61043941e47b6fa5c860b5c7a4f 100644 (file)
@@ -39,6 +39,7 @@ public:
   };
 
   bool init(int frame_width, int frame_height, enum SDL_Chroma chroma = SDL_CHROMA_420);
+  bool resize(int frame_width, int frame_height, enum SDL_Chroma chroma);
   void display(const unsigned char *Y, const unsigned char *U, const unsigned char *V,
                int stride, int chroma_stride);
   void close();